﻿using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using Model.Interfaces;

namespace Data.MappingClasses
{
    [TableAttribute(Name = "dbo.Address")]
    public partial class Address : AbstractMappingClass, INotifyPropertyChanging, INotifyPropertyChanged
    {

        private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

        private short _idAddress;

        private Nullable<short> _refStreet;

        private string _home;

        private Nullable<short> _room;

        private string _buildNumber;

        private EntitySet<School> _Schools;

        private EntitySet<Student> _Students;

        private EntityRef<Street> _Street;

        #region Extensibility Method Definitions
        partial void OnLoaded();
        partial void OnValidate(ChangeAction action);
        partial void OnCreated();
        partial void OnidAddressChanging(short value);
        partial void OnidAddressChanged();
        partial void OnrefStreetChanging(Nullable<short> value);
        partial void OnrefStreetChanged();
        partial void OnhomeChanging(string value);
        partial void OnhomeChanged();
        partial void OnroomChanging(Nullable<short> value);
        partial void OnroomChanged();
        partial void OnbuildNumberChanging(string value);
        partial void OnbuildNumberChanged();
        #endregion

        public Address()
        {
            this._Schools = new EntitySet<School>(AttachSchools, DetachSchools);
            this._Students = new EntitySet<Student>(AttachStudents, DetachStudents);
            this._Street = default(EntityRef<Street>);
            OnCreated();
        }

        [ColumnAttribute(Storage = "_idAddress", AutoSync = AutoSync.OnInsert, DbType = "SmallInt NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
        public short idAddress
        {
            get
            {
                return this._idAddress;
            }
            set
            {
                if ((this._idAddress != value))
                {
                    this.OnidAddressChanging(value);
                    this.SendPropertyChanging();
                    this._idAddress = value;
                    this.SendPropertyChanged("idAddress");
                    this.OnidAddressChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_refStreet", DbType = "SmallInt")]
        public Nullable<short> refStreet
        {
            get
            {
                return this._refStreet;
            }
            set
            {
                if ((this._refStreet != value))
                {
                    if (this._Street.HasLoadedOrAssignedValue)
                    {
                        throw new ForeignKeyReferenceAlreadyHasValueException();
                    }
                    this.OnrefStreetChanging(value);
                    this.SendPropertyChanging();
                    this._refStreet = value;
                    this.SendPropertyChanged("refStreet");
                    this.OnrefStreetChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_home", DbType = "VarChar(7)")]
        public string home
        {
            get
            {
                return this._home;
            }
            set
            {
                if ((this._home != value))
                {
                    this.OnhomeChanging(value);
                    this.SendPropertyChanging();
                    this._home = value;
                    this.SendPropertyChanged("home");
                    this.OnhomeChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_room", DbType = "SmallInt")]
        public Nullable<short> room
        {
            get
            {
                return this._room;
            }
            set
            {
                if ((this._room != value))
                {
                    this.OnroomChanging(value);
                    this.SendPropertyChanging();
                    this._room = value;
                    this.SendPropertyChanged("room");
                    this.OnroomChanged();
                }
            }
        }

        [ColumnAttribute(Storage = "_buildNumber", DbType = "VarChar(7)")]
        public string buildNumber
        {
            get
            {
                return this._buildNumber;
            }
            set
            {
                if ((this._buildNumber != value))
                {
                    this.OnbuildNumberChanging(value);
                    this.SendPropertyChanging();
                    this._buildNumber = value;
                    this.SendPropertyChanged("buildNumber");
                    this.OnbuildNumberChanged();
                }
            }
        }

        [AssociationAttribute(Name = "Address_School", Storage = "_Schools", ThisKey = "idAddress", OtherKey = "refAddress")]
        public EntitySet<School> Schools
        {
            get
            {
                return this._Schools;
            }
            set
            {
                this._Schools.Assign(value);
            }
        }

        [AssociationAttribute(Name = "Address_Student", Storage = "_Students", ThisKey = "idAddress", OtherKey = "refAddress")]
        public EntitySet<Student> Students
        {
            get
            {
                return this._Students;
            }
            set
            {
                this._Students.Assign(value);
            }
        }

        [AssociationAttribute(Name = "Street_Address", Storage = "_Street", ThisKey = "refStreet", OtherKey = "idStreet", IsForeignKey = true)]
        public Street Street
        {
            get
            {
                return this._Street.Entity;
            }
            set
            {
                Street previousValue = this._Street.Entity;
                if (((previousValue != value)
                     || (this._Street.HasLoadedOrAssignedValue == false)))
                {
                    this.SendPropertyChanging();
                    if ((previousValue != null))
                    {
                        this._Street.Entity = null;
                        previousValue.Addresses.Remove(this);
                    }
                    this._Street.Entity = value;
                    if ((value != null))
                    {
                        value.Addresses.Add(this);
                        this._refStreet = value.idStreet;
                    }
                    else
                    {
                        this._refStreet = default(Nullable<short>);
                    }
                    this.SendPropertyChanged("Street");
                }
            }
        }

        public event PropertyChangingEventHandler PropertyChanging;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void SendPropertyChanging()
        {
            if ((this.PropertyChanging != null))
            {
                this.PropertyChanging(this, emptyChangingEventArgs);
            }
        }

        protected virtual void SendPropertyChanged(String propertyName)
        {
            if ((this.PropertyChanged != null))
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private void AttachSchools(School entity)
        {
            this.SendPropertyChanging();
            entity.Address = this;
        }

        private void DetachSchools(School entity)
        {
            SendPropertyChanging();
            entity.Address = null;
        }

        private void AttachStudents(Student entity)
        {
            SendPropertyChanging();
            entity.Address = this;
        }

        private void DetachStudents(Student entity)
        {
            SendPropertyChanging();
            entity.Address = null;
        }

        public override Model.ModelClasses.AbstractModel PureModel
        {
            get
            {
                return base.PureModel;
            }
            set
            {
                if (_pureModel != null)
                {
                    _pureModel.UpdateModelEvent -= UpdateModelEventHandler;
                } 
                if(value != null)
                {
                    value.UpdateModelEvent += UpdateModelEventHandler;
                }
                _pureModel = value;
            }
        }

        private void UpdateModelEventHandler(object sender, EventArgs e)
        {
            var pureModel = ((IAddress) _pureModel);
            buildNumber = pureModel.Building;

            UpdateData();
        }
    }
}